// -----------------------------------------------------------------------
//  <copyright file="OsharpPack.cs" company="OSharp开源团队">
//      Copyright (c) 2014-2018 OSharp. All rights reserved.
//  </copyright>
//  <site>http://www.osharp.org</site>
//  <last-editor></last-editor>
//  <last-date>2018-07-25 12:03</last-date>
// -----------------------------------------------------------------------

namespace OSharp.Core.Packs;

/// <summary>
/// OSharp模块基类
/// </summary>
public abstract class OsharpPack
{
    /// <summary>
    /// 获取 模块级别，级别越小越先启动
    /// </summary>
    public virtual PackLevel Level => PackLevel.Business;

    /// <summary>
    /// 获取 模块启动顺序，模块启动的顺序先按级别启动，同一级别内部再按此顺序启动，
    /// 级别默认为0，表示无依赖，需要在同级别有依赖顺序的时候，再重写为>0的顺序值
    /// </summary>
    public virtual int Order => 0;

    /// <summary>
    /// 获取 是否已可用
    /// </summary>
    public bool IsEnabled { get; protected set; }

    /// <summary>
    /// 将模块服务添加到依赖注入服务容器中
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <returns></returns>
    public virtual IServiceCollection AddServices(IServiceCollection services)
    {
        return services;
    }

    /// <summary>
    /// 应用模块服务
    /// </summary>
    /// <param name="provider">服务提供者</param>
    public virtual void UsePack(IServiceProvider provider)
    {
        IsEnabled = true;
    }

    /// <summary>
    /// 获取当前模块的依赖模块类型
    /// </summary>
    /// <returns></returns>
    internal Type[] GetDependPackTypes(Type packType = null)
    {
        if (packType == null)
        {
            packType = GetType();
        }
        DependsOnPacksAttribute[] dependAttrs = packType.GetAttributes<DependsOnPacksAttribute>();
        if (dependAttrs.Length == 0)
        {
            return new Type[0];
        }
        List<Type> dependTypes = new List<Type>();
        foreach (DependsOnPacksAttribute dependAttr in dependAttrs)
        {
            Type[] packTypes = dependAttr.DependedPackTypes;
            if (packTypes.Length == 0)
            {
                continue;
            }
            dependTypes.AddRange(packTypes);
            foreach (Type type in packTypes)
            {
                dependTypes.AddRange(GetDependPackTypes(type));
            }
        }

        return dependTypes.Distinct().ToArray();
    }
}